#pragma once
#include "HikCamera.h"
#include <fstream>
#include <iostream>
#include <json/json.h>
#include <vector>
#include <map>
#include <mutex>
#include <opencv2/opencv.hpp>
#include <string>
#include "Robot.h"


extern std::string IP;
extern int Upper_Computer_Port;
extern int Controller_Port;
extern int Communication_Port;

// 上位机套接字
extern int Upper_Computer_fd;
// 控制器套接字
extern int Controller_fd;
// 示教器套接字
extern int Communication_fd;

// 机器人实时坐标
extern double _robot_x;
extern double _robot_y;
void updateRobot_xy(double x, double y);
double getRobot_x();
double getRobot_y();

// TCP字节通信长度
extern int Upper_Computer_Byte_Length;
extern int Controller_Byte_Length;

// 上位机接收数据
extern std::vector<uint8_t> ReceivedDataBufferUpper;
// 控制器接收数据
extern std::vector<uint8_t> ReceivedDataBufferController;
// 相机程序运行
extern bool IsServerStart;
// 9点标定，获取圆点位并发送
extern bool IsGetCirclePoint;
// 主程序根目录
extern const std::string executablePath;
// 日志文件夹，保存文件
extern const std::string LogFloderPath;
extern const std::string LogFilePath;
// 控制器基本配置文件
extern const std::string ConfigureFilePath;
// 模板JSON文件
extern const std::string SaveJsonPath;
// 模板文件夹
extern const std::string SaveImageFloderPath;
// 配置参数文件夹，文件名
extern const std::string ParamFloderPath;
extern const std::string ParamFilePath;
// 作业文件
extern const std::string JobFileFloderPath;
// 与上位机通信，图像压缩维度
extern const cv::Size IMAGE_SIZE;
// 标定，映射矩形维度
extern const cv::Size AFFINE_SIZE;
// 创建相机全局对象
extern HikCamera camera;

//  相机与机器人坐标
extern std::vector<cv::Point2f> CameraCalibrations;
extern std::vector<cv::Point2f> RobotCalibrations;
extern int camera_target_x, camera_target_y;
extern double robot_target_x, robot_target_y;
void updateCameraCalibrations(std::vector<cv::Point2f> value);
std::vector<cv::Point2f> getCameraCalibrations();
void updateRobotCalibrations(std::vector<cv::Point2f> &value);
std::vector<cv::Point2f> getRobotCalibrations();

// 获取更新机器人抓取状态
extern bool RobotGrasping;
void updateRobotGrasping(bool value);
bool getRobotGrasping();

//  获取图像宽高参数
extern std::map<std::string, int> CamWHParam;
void updateCamWHParam(const std::string &key, int value);
int getCamWHParam(const std::string &key);

//  获取图像偏移量参数
extern std::map<std::string, int> CamXYParam;
void updateCamXYParam(const std::string &key, int value);
int getCamXYParam(const std::string &key);

//  获取图像二值化参数
extern std::map<std::string, int> BinarParam;
void updateBinarParam(const std::string &key, int value);
int getBinarParam(const std::string &key);

//  获取图像圆查找参数
extern std::map<std::string, int> CircleParam;
void updateCircleParam(const std::string &key, int value);
int getCircleParam(const std::string &key);

//ROI区域 圆查找
extern std::map<std::string, std::map<std::string, int>> Circle_ROI;
void updateCircleROI(const std::string &key, std::map<std::string, int> value);
std::map<std::string, int> getCircleROI(const std::string &key);

//  获取图像矩形查找参数
extern std::map<std::string, int> RentangleParam;
void updateRentangleParam(const std::string &key, int value);
int getRentangleParam(const std::string &key);

//ROI区域 矩形检测
extern std::map<std::string, std::map<std::string, int>> Rentangle_ROI;
void updateRentangleROI(const std::string &key, std::map<std::string, int> value);
std::map<std::string, int> getRentangleROI(const std::string &key);

//  获取图像模板匹配模板参数
/*
  std::map<std::string, std::map<std::string, int>> TemplatePoints = {
      {"Point1", {{"PointX", 0}, {"PointY", 0}}},
      {"Point2", {{"PointX", 0}, {"PointY", 0}}}};
*/
struct TemplateParam
{
  std::string TemplateId;
  std::string TemplateName;
  std::map<std::string, std::map<std::string, int>> TemplatePoints;
};

// ROI区域 模板匹配
extern std::map<std::string, std::map<std::string, int>> Template_ROI;
void updateTemplateROI(const std::string &key, std::map<std::string, int> value);
std::map<std::string, int> getTemplateROI(const std::string &key);

// 临时模板参数
extern cv::Mat templateImg;
extern cv::Mat cropped_img;
extern TemplateParam templateP;

extern cv::Mat inputTempl;
void updateinputTempl(cv::Mat img);
cv::Mat getinputTempl();

void updatetemplateP(TemplateParam templateP_tmp);
TemplateParam gettemplateP();

// 创建的所有模板参数
extern std::map<std::string, struct TemplateParam> TemplateParamMap;
void updateTemplateParam(const std::string &key, struct TemplateParam value);
struct TemplateParam getTemplateParam(const std::string &key);

// 将TemplateParamMap的数据以Json文件的形式保存读取
void TemplateParamMapRead(
    std::map<std::string, struct TemplateParam> &TemplateParamMap);
void TemplateParamMapWrite(
    std::map<std::string, struct TemplateParam> &TemplateParamMap);


